#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
ChainMaker连接测试脚本
使用配置文件创建ChainClient来测试长安链连接、区块查询、交易查询和合约调用等功能
"""

import os
import sys
import time
import json
import base64
import binascii
from google.protobuf import json_format # 导入json_format
from chainmaker.chain_client import ChainClient
from chainmaker.protos.common.request_pb2 import Payload, TxType, KeyValuePair
from chainmaker.keys import RuntimeType
from chainmaker.payload import PayloadBuilder
import uuid

# 配置文件路径
CONFIG_FILE = 'c:\\Users\\junhu\\Documents\\code\\jiaoda_blockchain\\adapters\\chainmaker\\sdk_config.yml'

# 测试参数
CHAIN_ID = 'simmed'  # 链ID
ORG_ID = 'TestCMorg1'  # 组织ID

def print_separator(title=""):
    """打印分隔符"""
    width = 80
    if title:
        print(f"\n{'=' * 10} {title} {'=' * (width - len(title) - 12)}")
    else:
        print(f"\n{'=' * width}")

def test_chainmaker_from_config():
    """使用配置文件创建ChainClient进行测试"""
    try:
        print_separator("使用配置文件创建ChainClient进行测试")
        print(f"配置文件路径: {CONFIG_FILE}")
        print(f"链ID: {CHAIN_ID}")
        print(f"组织ID: {ORG_ID}")
        
        # 检查配置文件是否存在
        if not os.path.exists(CONFIG_FILE):
            print(f"错误: 配置文件不存在: {CONFIG_FILE}")
            return False
        
        # 创建ChainClient
        print_separator("创建ChainClient")
        chain_client = ChainClient.from_conf(CONFIG_FILE)
        print("ChainClient 初始化成功")

        

        # 获取链版本
        print_separator("获取链版本")
        version = chain_client.get_chainmaker_server_version()
        print(f"ChainMaker版本: {version}")


        
        # 获取最新区块高度
        print_separator("获取最新区块高度")
        block_height = chain_client.get_current_block_height()
        print(f"当前区块高度: {block_height}")
        
        # 获取链信息
        print_separator("获取链信息")
        try:
            chain_info = chain_client.get_chain_info()
            print(f"链ID: {chain_info.chain_id}")
            print(f"区块高度: {chain_info.block_height}")
            print(f"节点数量: {len(chain_info.node_list) if hasattr(chain_info, 'node_list') else '未知'}")
        except Exception as e:
            print(f"获取链信息失败: {e}")
        
        # 获取区块数据测试
        print_separator("获取区块数据测试")
        try:
            # 获取创世区块（高度为1）
            print("\n获取创世区块（高度为1）...")
            genesis_block = chain_client.get_block_by_height(1, with_rw_set=True)
            if genesis_block:
                print("创世区块获取成功")
                print_block_info_minimal(genesis_block)
            else:
                print("创世区块获取失败")
            
            # 获取最新区块
            if block_height > 1:
                print("\n获取最新区块...")
                try:
                    latest_block = chain_client.get_block_by_height(block_height, with_rw_set=True)
                    if latest_block:
                        print("最新区块获取成功")
                        print_block_info_minimal(latest_block)
                        
                        # 如果有交易，尝试获取第一个交易详情
                        if hasattr(latest_block.block, 'txs') and latest_block.block.txs:
                            first_tx = latest_block.block.txs[0]
                            tx_id = None
                            for tx_field, tx_value in first_tx.ListFields():
                                if tx_field.name == 'tx_id':
                                    tx_id = tx_value
                                    break
                            
                            if tx_id:
                                print_separator("获取交易详情")
                                print(f"交易ID: {tx_id}")
                                try:
                                    tx_info = chain_client.get_tx_by_tx_id(tx_id, with_rw_set=True)
                                    if tx_info:
                                        print("交易详情获取成功")
                                        print_tx_info_minimal(tx_info)
                                    else:
                                        print("交易详情获取失败")
                                except Exception as e:
                                    print(f"获取交易详情失败: {e}")
                    else:
                        print("最新区块获取失败")
                except Exception as e:
                    print(f"获取最新区块失败: {e}")
                
        except Exception as e:
            print(f"获取区块数据测试失败: {e}")
        
        # 导入 RuntimeType
        from chainmaker.protos.common import contract_pb2
        RuntimeType = contract_pb2.RuntimeType

        
        # # 后续测试可以继续使用 chain_client
        # 调用WASM合约 simple_storage
        print_separator("调用WASM合约 simple_storage 测试")
        contract_name = 'simple_storage'
        
        # 测试 set 方法
        print("\n测试 set 方法...")
        set_key = "test_key_wasm1"
        set_value = "test_value_wasm1"
        res_set = None # Initialize
        try:
            # 调用WASM合约
            payload = chain_client._payload_builder.create_invoke_payload(contract_name,"set",{"key": set_key, "value": set_value})

            response = chain_client.send_request_with_sync_result(payload)

            print(response)

            payload = chain_client._payload_builder.create_invoke_payload(contract_name,"get",{"key": set_key})

            response = chain_client.send_request_with_sync_result(payload)

            print(response)
        except AttributeError as ae:
            print(f"调用 chain_client.invoke_contract('set') 时发生 AttributeError: {ae}")
        except Exception as e_invoke:
            print(f"调用 chain_client.invoke_contract('set') 时发生其他异常: {e_invoke}")

        return True
        
    except Exception as e:
        print(f"测试失败，错误: {e}")
        return False


def print_block_info_minimal(block_data):
    """打印区块信息 - 极简版"""
    try:
        print("\n=== 区块信息极简版 ===")
        
        # 使用ListFields方法获取所有字段
        if hasattr(block_data, 'ListFields'):
            fields = block_data.ListFields()
            for field, value in fields:
                print(f"字段: {field.name}, 类型: {type(value)}")
                
                # 如果是block字段，进一步处理
                if field.name == 'block':
                    block = value
                    
                    # 获取区块头信息 - 只打印关键字段
                    if hasattr(block, 'header') and block.header:
                        header = block.header
                        print("\n区块头关键信息:")
                        key_header_fields = ['block_height', 'block_hash', 'pre_block_hash', 'block_timestamp']
                        for header_field, header_value in header.ListFields():
                            if header_field.name in key_header_fields:
                                if header_field.name.endswith('_hash'):
                                    # 对哈希值进行十六进制编码显示
                                    hex_value = binascii.hexlify(header_value).decode('utf-8')
                                    print(f"  {header_field.name}: {hex_value}")
                                elif header_field.name == 'block_timestamp':
                                    # 转换时间戳为可读格式
                                    time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(header_value))
                                    print(f"  {header_field.name}: {header_value} ({time_str})")
                                else:
                                    print(f"  {header_field.name}: {header_value}")
                    
                    # 获取交易列表 - 只打印数量
                    if hasattr(block, 'txs') and block.txs:
                        tx_count = len(block.txs)
                        print(f"\n交易数量: {tx_count}")
                        if tx_count > 0:
                            # 只打印第一个交易的ID
                            first_tx = block.txs[0]
                            for tx_field, tx_value in first_tx.ListFields():
                                if tx_field.name == 'tx_id':
                                    print(f"第一个交易ID: {tx_value}")
                                    break
                    break  # 只处理block字段，其他字段跳过
            
    except Exception as e:
        print(f"打印区块信息失败: {e}")


def print_tx_info_minimal(tx_info):
    """打印交易信息 - 极简版"""
    try:
        print("\n=== 交易信息极简版 ===")
        
        # 使用ListFields方法获取所有字段
        if hasattr(tx_info, 'ListFields'):
            fields = tx_info.ListFields()
            for field, value in fields:
                print(f"字段: {field.name}, 类型: {type(value)}")
                
                # 如果是transaction字段，进一步处理
                if field.name == 'transaction':
                    tx = value
                    
                    # 获取交易关键信息
                    key_tx_fields = ['tx_id', 'timestamp', 'tx_type', 'sender']
                    print("\n交易关键信息:")
                    for tx_field, tx_value in tx.ListFields():
                        if tx_field.name in key_tx_fields:
                            if tx_field.name == 'timestamp':
                                # 转换时间戳为可读格式
                                time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(tx_value/1000000000))
                                print(f"  {tx_field.name}: {tx_value} ({time_str})")
                            else:
                                print(f"  {tx_field.name}: {tx_value}")
                    
                    # 如果有合约调用信息，打印合约名称和方法
                    if hasattr(tx, 'payload') and tx.payload:
                        payload = tx.payload
                        if hasattr(payload, 'contract_name') and payload.contract_name:
                            print(f"  contract_name: {payload.contract_name}")
                        if hasattr(payload, 'method') and payload.method:
                            print(f"  method: {payload.method}")
                    break  # 只处理transaction字段，其他字段跳过
                
                # 如果是result字段，进一步处理
                if field.name == 'result':
                    result = value
                    print("\n交易结果:")
                    for result_field, result_value in result.ListFields():
                        print(f"  {result_field.name}: {result_value}")
            
    except Exception as e:
        print(f"打印交易信息失败: {e}")


if __name__ == "__main__":
    # 使用配置文件形式创建ChainClient进行测试
    result = test_chainmaker_from_config()
    
    if result:
        print("\n连接测试成功！")
        sys.exit(0)
    else:
        print("\n连接测试失败！")
        sys.exit(1)